//
//  UIPasteboard.swift
//  Documentation
//
//  Created by Toj on 3/26/24.
//
// UIPasteboard 是 Swift 中用于存储和检索应用程序中剪贴板中的数据的一个类.
// 剪贴板是应用程序之间共享数据的一种机制,
// UIPasteboard 提供了一种简单的方式来存储和检索应用程序中的剪贴板数据
//

import Foundation

extension UIPasteboard.Name {

    public static let general: UIPasteboard.Name
}

// 丢弃
@available(iOS, introduced: 3.0, deprecated: 10.0, message: "The Find pasteboard is no longer available.")
public let UIPasteboardNameFind: String
extension UIPasteboard.DetectionPattern {

    
    /// NSString value, suitable for implementing "Paste and Go"
    @available(iOS 14.0, *)
    public static let probableWebURL: UIPasteboard.DetectionPattern

    
    /// NSString value, suitable for implementing "Paste and Search"
    @available(iOS 14.0, *)
    public static let probableWebSearch: UIPasteboard.DetectionPattern

    
    /// NSNumber value
    @available(iOS 14.0, *)
    public static let number: UIPasteboard.DetectionPattern
}

@available(iOS 3.0, *)
open class UIPasteboard : NSObject, @unchecked Sendable {

    /// 系统级的剪切板
    open class var general: UIPasteboard { get }

    
    /// 自定义剪切板
    public /*not inherited*/ init?(name pasteboardName: UIPasteboard.Name, create: Bool)

    open class func withUniqueName() -> UIPasteboard

    /// 剪切板名字
    open var name: UIPasteboard.Name { get }

    
    /// 移除某个剪切板
    open class func remove(withName pasteboardName: UIPasteboard.Name)

    /// 是否进行持久化
    open var isPersistent: Bool { get }

    @available(iOS, introduced: 3.0, deprecated: 10.0, message: "Do not set persistence on pasteboards. This property is set automatically.")
    open func setPersistent(_ persistent: Bool)

    /// 此剪切板的改变次数 系统级别的剪切板只有当设备重新启动时 这个值才会清零/
    open var changeCount: Int { get }

    
    // Item provider interface
    
    @available(iOS 11.0, *)
    open var itemProviders: [NSItemProvider]

    
    @available(iOS 11.0, *)
    open func setItemProviders(_ itemProviders: [NSItemProvider], localOnly: Bool, expirationDate: Date?)

    
    // Automatically creates item providers wrapping the objects passed in.
    @available(iOS 11.0, *)
    open func setObjects(_ objects: [NSItemProviderWriting])

    @available(iOS 11.0, *)
    open func setObjects(_ objects: [NSItemProviderWriting], localOnly: Bool, expirationDate: Date?)

    
    // First item
    
    open var types: [String] { get }

    open func contains(pasteboardTypes: [String]) -> Bool

    open func data(forPasteboardType pasteboardType: String) -> Data?

    
    open func value(forPasteboardType pasteboardType: String) -> Any?

    
    open func setValue(_ value: Any, forPasteboardType pasteboardType: String)

    open func setData(_ data: Data, forPasteboardType pasteboardType: String)

    
    // Multiple items
    
    open var numberOfItems: Int { get }

    open func types(forItemSet itemSet: IndexSet?) -> [[String]]?

    
    open func contains(pasteboardTypes: [String], inItemSet itemSet: IndexSet?) -> Bool

    open func itemSet(withPasteboardTypes pasteboardTypes: [String]) -> IndexSet?

    open func values(forPasteboardType pasteboardType: String, inItemSet itemSet: IndexSet?) -> [Any]?

    open func data(forPasteboardType pasteboardType: String, inItemSet itemSet: IndexSet?) -> [Data]?

    
    // Direct access
    
    open var items: [[String : Any]]

    open func addItems(_ items: [[String : Any]])

    
    // Value: NSDate.
    // Value: NSNumber, boolean.
    
    @available(iOS 10.0, *)
    open func setItems(_ items: [[String : Any]], options: [UIPasteboard.OptionsKey : Any] = [:])

    
    open var string: String?

    open var strings: [String]?

    
    open var url: URL?

    open var urls: [URL]?

    
    @NSCopying open var image: UIImage?

    open var images: [UIImage]?

    
    @NSCopying open var color: UIColor?

    open var colors: [UIColor]?

    
    // Queries
    
    @available(iOS 10.0, *)
    open var hasStrings: Bool { get }

    @available(iOS 10.0, *)
    open var hasURLs: Bool { get }

    @available(iOS 10.0, *)
    open var hasImages: Bool { get }

    @available(iOS 10.0, *)
    open var hasColors: Bool { get }
}

extension UIPasteboard {

    @available(iOS 15.0, *)
    public struct DetectedValues {

        public var patterns: Set<PartialKeyPath<UIPasteboard.DetectedValues>> { get }

        public var probableWebURL: String { get }

        public var probableWebSearch: String { get }

        public var number: Double? { get }

        public var links: [DDMatchLink] { get }

        public var phoneNumbers: [DDMatchPhoneNumber] { get }

        public var emailAddresses: [DDMatchEmailAddress] { get }

        public var postalAddresses: [DDMatchPostalAddress] { get }

        public var calendarEvents: [DDMatchCalendarEvent] { get }

        public var shipmentTrackingNumbers: [DDMatchShipmentTrackingNumber] { get }

        public var flightNumbers: [DDMatchFlightNumber] { get }

        public var moneyAmounts: [DDMatchMoneyAmount] { get }
    }
}

extension UIPasteboard {

    /// Detects patterns in the first pasteboard item.
    ///
    /// - Parameters:
    ///   - patterns: Detect only these patterns.
    ///   - completionHandler: Receives which patterns were detected, or an error.
    @available(iOS, introduced: 14.0, deprecated: 15.0)
    public func detectPatterns(for patterns: Set<UIPasteboard.DetectionPattern>, completionHandler: @escaping (Result<Set<UIPasteboard.DetectionPattern>, Error>) -> ())

    @available(iOS 15.0, *)
    public func detectPatterns(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, completionHandler: @escaping (Result<Set<PartialKeyPath<UIPasteboard.DetectedValues>>, Error>) -> ())

    @available(iOS 15.0, *)
    public func detectedPatterns(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>) async throws -> Set<PartialKeyPath<UIPasteboard.DetectedValues>>

    /// Detects patterns in the specified pasteboard items.
    ///
    /// - Parameters:
    ///   - patterns: Detect only these patterns.
    ///   - itemSet: Specifies which pasteboard items by their position. Nil means all items.
    ///   - completionHandler: Receives which patterns were detected per item specified,
    ///                        or an error.
    @available(iOS, introduced: 14.0, deprecated: 15.0)
    public func detectPatterns(for patterns: Set<UIPasteboard.DetectionPattern>, inItemSet itemSet: IndexSet?, completionHandler: @escaping (Result<[Set<UIPasteboard.DetectionPattern>], Error>) -> ())

    @available(iOS 15.0, *)
    public func detectPatterns(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, inItemSet itemSet: IndexSet?, completionHandler: @escaping (Result<[Set<PartialKeyPath<UIPasteboard.DetectedValues>>], Error>) -> ())

    @available(iOS 15.0, *)
    public func detectedPatterns(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, inItemSet itemSet: IndexSet?) async throws -> [Set<PartialKeyPath<UIPasteboard.DetectedValues>>]

    /// Detects patterns and corresponding values in the first pasteboard item.
    ///
    /// - Parameters:
    ///   - patterns: Detect only these patterns.
    ///   - completionHandler: Receives which patterns and values were detected, or an error.
    @available(iOS, introduced: 14.0, deprecated: 15.0)
    public func detectValues(for patterns: Set<UIPasteboard.DetectionPattern>, completionHandler: @escaping (Result<[UIPasteboard.DetectionPattern : Any], Error>) -> ())

    @available(iOS 15.0, *)
    public func detectValues(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, completionHandler: @escaping (Result<UIPasteboard.DetectedValues, Error>) -> ())

    @available(iOS 15.0, *)
    public func detectedValues(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>) async throws -> UIPasteboard.DetectedValues

    /// Detects patterns and corresponding values in the specified pasteboard items.
    ///
    /// - Parameters:
    ///   - patterns: Detect only these patterns.
    ///   - itemSet: Specifies which pasteboard items by their position. Nil means all items.
    ///   - completionHandler: Receives which patterns and values were detected per item specified,
    ///                        or an error.
    @available(iOS, introduced: 14.0, deprecated: 15.0)
    public func detectValues(for patterns: Set<UIPasteboard.DetectionPattern>, inItemSet itemSet: IndexSet?, completionHandler: @escaping (Result<[[UIPasteboard.DetectionPattern : Any]], Error>) -> ())

    @available(iOS 15.0, *)
    public func detectValues(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, inItemSet itemSet: IndexSet?, completionHandler: @escaping (Result<[UIPasteboard.DetectedValues], Error>) -> ())

    @available(iOS 15.0, *)
    public func detectedValues(for keyPaths: Set<PartialKeyPath<UIPasteboard.DetectedValues>>, inItemSet itemSet: IndexSet?) async throws -> [UIPasteboard.DetectedValues]
}

extension UIPasteboard {

    @available(iOS 11.0, *)
    public func setObjects<T>(_ objects: [T]) where T : _ObjectiveCBridgeable, T._ObjectiveCType : NSItemProviderWriting

    @available(iOS 11.0, *)
    public func setObjects<T>(_ objects: [T], localOnly: Bool, expirationDate: Date?) where T : _ObjectiveCBridgeable, T._ObjectiveCType : NSItemProviderWriting
}
extension UIPasteboard {

    @available(iOS 10.0, *)
    public struct OptionsKey : Hashable, Equatable, RawRepresentable, @unchecked Sendable {

        public init(rawValue: String)
    }

    
    // Notification
    
    public class let changedNotification: NSNotification.Name

    public class let changedTypesAddedUserInfoKey: String

    public class let changedTypesRemovedUserInfoKey: String

    
    public class let removedNotification: NSNotification.Name

    
    // Types
    
    public class var typeListString: NSArray

    public class var typeListURL: NSArray

    public class var typeListImage: NSArray

    public class var typeListColor: NSArray

    
    // Use the following type in setItems: or setItems:options: to automatically insert appropriate UTIs for supported types.
    // Supported types are: NSString, NSURL, UIImage, UIColor, NSAttributedString.
    @available(iOS 10.0, *)
    public class let typeAutomatic: String

    public struct Name : Hashable, Equatable, RawRepresentable, @unchecked Sendable {

        public init(_ rawValue: String)

        public init(rawValue: String)
    }

    @available(iOS 14.0, *)
    public struct DetectionPattern : Hashable, Equatable, RawRepresentable, @unchecked Sendable {

        public init(rawValue: String)
    }
}
extension UIPasteboard.OptionsKey {

    @available(iOS 10.0, *)
    public static let expirationDate: UIPasteboard.OptionsKey

    @available(iOS 10.0, *)
    public static let localOnly: UIPasteboard.OptionsKey
}
